from re import X
from manimlib import *
from os import system

class geometry(Scene):
    def construct(self):
        colors = [BLUE, RED, GREEN]
        vectors = [
            np.array([1, 0]),
            np.array([1, 1]),
            np.array([1, 3]),
            np.array([-2, 1]),
            np.array([-1, -1])
        ]
        
        temp_vec, temp_text = None, None
        for index, v in enumerate(vectors):
            if not self.get_mobjects():     # 检查Scene画布上有没有放实体，没有就放，你也可以通过temp_vec是否为None来等价判断，这个地方只是单纯想让你知道有get_mobjects这个方法
                temp_vec = Vector(
                    direction=v,
                    fill_color=colors[index % len(colors)]
                )
                temp_text = Tex(f"({v[0]}, {v[1]})")
                temp_text.move_to(np.hstack((v, 0)) * 1.2)      # move_to的参数必须是三维向量
                self.add(temp_vec, temp_text)
            else:
                cur_vec = Vector(
                    direction=v,
                    fill_color=colors[index % len(colors)]
                )
                cur_text = Tex(f"({v[0]}, {v[1]})")
                cur_text.move_to(np.hstack((v, 0)) * 1.2)
                self.play(
                    ReplacementTransform(temp_vec, cur_vec),
                    ReplacementTransform(temp_text, cur_text)
                )
                temp_vec = cur_vec
                temp_text = cur_text

class Gauss(Scene):
    def construct(self):
        axes = Axes((0,60,5), (0, 10))
        axes.add_coordinate_labels(font_size=10,
            num_decimal_places=1,)

        self.play(Write(axes, lag_ratio=10, run_time = 0.5))

        gauss_graph = axes.get_graph(
            lambda x: 8 * math.exp(-(x - 45) ** 2 / 50),
            color=BLUE,
        )

        gauss_label = axes.get_graph_label(gauss_graph, "gauss")
        
        self.play(
            ShowCreation(gauss_graph),
            FadeIn(gauss_label, RIGHT),
        )
        self.wait(2)

        for x in [30.67, 46.35, 54.29, 46.38, 50.94, 48.39]:
            dot = Dot(color=RED)
            dot.move_to(axes.i2gp(x, gauss_graph))
            self.play(FadeIn(dot, scale=0.2))
            self.wait(0.2)


# 折线图demo
class scatter(Scene):
    def construct(self):
        # 点的序列，注意 np.array 后的逗号
        points = [
            np.array([-2, 1, 0]),
            np.array([-1, 0, 0]),
            np.array([1, 0, 0]),
            np.array([2, 1, 0]),
            np.array([1, 1, 0])
        ]
        names = ["a1", "a2", "a3", "a4", "a5"]     # 点的名字
        
        # 创建坐标轴
        axes = Axes(
            x_range=(-2, 2),
            y_range=(0, 1.2)
        )
        
        axes.add_coordinate_labels()
       
        self.play(Write(axes))
        
        ll = DashedLine(
            start = axes.c2p(0, 0),
            end = axes.c2p(1, 1),
        )
        self.play(ShowCreation(ll))

        # 将三阶贝塞尔曲线的三条外边画出来，并加上*names的标注
        for i, _ in enumerate(points):
            if i < len(points) - 1:
                text = self.write_word(names[i], axes.c2p(points[i][0], points[i][1]))
                self.play(
                    ShowCreation(axes.get_graph(
                        function = self.get_line_func(points[i], points[i + 1]),
                        x_range = (points[i][0], points[i + 1][0]),
                        color = BLUE)),
                    Write(text)
                )

        text = self.write_word(names[-1], axes.c2p(points[-1][0], points[-1][1]))
        self.play(Write(text))

    # 添加标注
    def write_word(self, words, position=ORIGIN):
        t = Tex(words, color=GREEN_B)
        t.move_to(position)
        return t
    
    # 两点确定的直线方程
    def get_line_func(self, point1, point2):    
        if point1[0] == point2[0]:
            return lambda x : point1[0]
        else:
            k = (point2[1] - point1[1]) / (point2[0] - point1[0])
            b = point1[1] - k * point1[0]
            return lambda x : k * x + b

# 多个坐标系
# 创建二维坐标系，并在(1,1)处创建一个蓝色的点
class demo(Scene):
    def construct(self):
        axe_config = {
            "height" : 10, "width" : 15, 
            "x_range" : (0, 15), "y_range" : (0, 10)
        }
        axe1 = Axes(**axe_config)
        axe2 = Axes(**axe_config)
        axe1.add_coordinate_labels()
        axe2.add_coordinate_labels()
        axe1.set_color(BLUE)
        axe2.set_color(GREEN)
        #axe1.move_to(np.array([5, 3, 0]))
        #axe2.move_to(np.array([-5, -2, 0]))

        self.play(ShowCreation(axe1), ShowCreation(axe2), run_time=1.5)

        self.play(
            axe1.animate.scale(0.75).to_corner(LEFT_SIDE),
            run_time=2,
        )
        self.play(
            axe2.animate.scale(0.75).to_corner(RIGHT_SIDE),
            run_time=2,
        )

        self.wait()
